package network

import (
	"bytes"
	"encoding/binary"
	"io"
	"sync"
)

var headerSize = 4

var headerBufPool = &sync.Pool{
	New: func() any {
		v := make([]byte, headerSize)
		return &v
	},
}

type defaultCodec struct{}

func (codec *defaultCodec) Pack(payload []byte, buf *bytes.Buffer) (err error) {
	headerBuf := headerBufPool.Get().(*[]byte)
	defer headerBufPool.Put(headerBuf)

	binary.BigEndian.PutUint32(*headerBuf, uint32(len(payload)))
	buf.Write(*headerBuf)
	buf.Write(payload)
	return
}

func (codec *defaultCodec) Unpack(reader io.Reader) (payload []byte, err error) {
	headerBuf := headerBufPool.Get().(*[]byte)
	defer headerBufPool.Put(headerBuf)

	_, err = io.ReadAtLeast(reader, *headerBuf, headerSize)
	if err != nil {
		return
	}

	length := binary.BigEndian.Uint32(*headerBuf)
	payload = make([]byte, length)

	_, err = io.ReadFull(reader, payload)
	return
}
